home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / unix / cshel40a / part02 < prev    next >
Encoding:
Internet Message Format  |  1990-01-15  |  46.6 KB

  1. Path: xanth!cs.odu.edu!Amiga-Request
  2. From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v90i015: CShell 4.00A - alternative command interface, Part02/04
  5. Message-ID: <10988@xanth.cs.odu.edu>
  6. Date: 15 Jan 90 16:28:51 GMT
  7. Sender: tadguy@cs.odu.edu
  8. Reply-To: PERUGIA@ICNUCEVM.CNUCE.CNR.IT (Carlo & Cesare)
  9. Lines: 2076
  10. Approved: tadguy@cs.odu.edu (Tad Guy)
  11.  
  12. Submitted-by: PERUGIA@ICNUCEVM.CNUCE.CNR.IT (Carlo & Cesare)
  13. Posting-number: Volume 90, Issue 015
  14. Archive-name: unix/cshell-4.00a/part02
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then unpack
  18. # it by saving it into a file and typing "sh file".  To overwrite existing
  19. # files, type "sh file -c".  You can also feed this as standard input via
  20. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  21. # will see the following message at the end:
  22. #        "End of archive 2 (of 4)."
  23. # Contents:  comm1.c comm2.c sub.c
  24. # Wrapped by tadguy@xanth on Mon Jan 15 11:28:09 1990
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f 'comm1.c' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'comm1.c'\"
  28. else
  29. echo shar: Extracting \"'comm1.c'\" \(16508 characters\)
  30. sed "s/^X//" >'comm1.c' <<'END_OF_FILE'
  31. X/*
  32. X * COMM1.C
  33. X *
  34. X * Matthew Dillon, August 1986
  35. X *
  36. X * Version 2.07M by Steve Drew 10-Sep-87
  37. X *
  38. X * Version 4.00A by Carlo Borreo & Cesare Dieni 13-Jan-90
  39. X *
  40. X */
  41. X
  42. X#define DIR_SHORT 0x01
  43. X#define DIR_FILES 0x02
  44. X#define DIR_DIRS  0x04
  45. X#define DIR_NOCOL 0x08
  46. X#define DIR_NAMES 0x10
  47. X
  48. Xextern int has_wild;
  49. X
  50. X/*
  51. X    Parse the options specified in sw[]
  52. X    Setting a bit in global variable options
  53. X    for each one found
  54. X*/
  55. X
  56. Xget_opt(sw,count)
  57. Xchar *sw;
  58. Xint *count;
  59. X{
  60. Xregister char *c,*s;
  61. Xunsigned int l,i = 0;
  62. X
  63. Xoptions=0;
  64. Xwhile((++i < ac) && (av[i][0] == '-')) {
  65. X    for (c = av[i]+1; *c ; c++) {
  66. X        for(l = 0,s = sw;*s && *s != *c; ++s) ++l;
  67. X        if (*s) options |= (1 << l);
  68. X        }
  69. X    }
  70. X*count = i;
  71. X}
  72. X
  73. Xdo_sleep()
  74. X{
  75. Xregister int i;
  76. X
  77. Xif (ac == 2) for (i=atoi(av[1]); i>0 && !CHECKBREAK(); i-=2) Delay(100L);
  78. Xreturn 0;
  79. X}
  80. X
  81. Xdo_protect()
  82. X{
  83. Xregister long mask=0xf;
  84. Xregister char *s, *p;
  85. Xstatic char flags[]="DEWRAPSH";
  86. Xregister unsigned short i;
  87. X
  88. Xfor (s=av[--ac]; *s; s++)
  89. X    if (p=index(flags, toupper(*s))) mask^=(1 << (p-flags));
  90. X    else ierror(av[ac],500);
  91. Xfor (i=1; i<ac; i++) if (!SetProtection(av[i],mask)) pError(av[i]);
  92. Xreturn 0;
  93. X}
  94. X
  95. Xdo_filenote()
  96. X{
  97. Xchar *note=av[--ac];
  98. Xregister unsigned int i;
  99. X
  100. Xfor (i=1; i<ac; i++) if (!SetComment(av[i], note)) pError(av[i]);
  101. Xreturn 0;
  102. X}
  103. X
  104. Xdo_cat()
  105. X{
  106. XFILE *fopen(), *fi;
  107. Xregister unsigned int lctr;
  108. Xunsigned int i;
  109. Xchar buf[256];
  110. X
  111. Xget_opt("n",&i);
  112. Xif (i>=ac) {
  113. X    if (has_wild) { printf("No files matching\n"); return 20; }
  114. X    lctr=0;
  115. X    while (gets(buf) && !dobreak()) {
  116. X        if (options) printf("%4d ",++lctr);
  117. X        puts(buf);
  118. X        }
  119. X    }
  120. Xfor (; i<ac; i++)
  121. X    if (fi = fopen (av[i], "r")) {
  122. X        lctr=0;
  123. X        while (fgets(buf,256,fi) && !dobreak()) {
  124. X            if (options) printf("%4d ",++lctr);
  125. X            printf("%s",buf);
  126. X            }
  127. X        fclose (fi);
  128. X        }
  129. X    else pError(av[i]);
  130. Xreturn 0;
  131. X}
  132. X
  133. Xdo_info()
  134. X{
  135. XBPTR lock;
  136. Xstruct InfoData *info;
  137. Xlong size, free;
  138. Xchar *p, buf[130], *state;
  139. Xstruct DirectoryEntry *de_head=NULL, *de;
  140. X
  141. Xinfo=(struct InfoData *)AllocMem((long)sizeof(struct InfoData),MEMF_PUBLIC);
  142. XAddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY );
  143. XMyprocess->pr_WindowPtr = (APTR)(-1);
  144. Xprintf ("Unit  Size  Bytes  Used Blk/By-Free Full Errs  Status    Name\n");
  145. Xfor (de=de_head; de; de=de->de_Next) {
  146. X    printf("%-5s",de->de_Name);
  147. X    if (lock=Lock(de->de_Name,ACCESS_READ)) {
  148. X        if (Info(lock, info)) {
  149. X        PathName(lock, buf, 128L);
  150. X        if (p=index(buf,':')) *p = '\0';
  151. X        size = ((info->id_NumBlocks + 2)* info->id_BytesPerBlock)/ 1024;
  152. X        free = (((info->id_NumBlocks-info->id_NumBlocksUsed))*
  153. X               info->id_BytesPerBlock)/ 1024;
  154. X        switch(info->id_DiskState) {
  155. X            case ID_WRITE_PROTECTED: state="Read Only "; break;
  156. X            case ID_VALIDATED:     state="Read/Write"; break;
  157. X            case ID_VALIDATING:     state="Validating"; break;
  158. X            }
  159. X        printf("%4ld%c%6ld%7ld%7ld%4ld%c%4ld%%%4ld  %s %s\n",
  160. X            (size>1024) ? ((size+512) >> 10) : size,
  161. X            (size>1024) ? 'M' : 'K',
  162. X            info->id_BytesPerBlock,
  163. X            info->id_NumBlocksUsed,
  164. X            info->id_NumBlocks-info->id_NumBlocksUsed,
  165. X            (free>1024) ? ((free+512) >> 10) : free,
  166. X            (free>1024) ? 'M' : 'K',
  167. X            (info->id_NumBlocksUsed * 100)/info->id_NumBlocks,
  168. X            info->id_NumSoftErrors,
  169. X            state,
  170. X            buf);
  171. X        }
  172. X        else pError (de->de_Name);
  173. X        UnLock(lock);
  174. X        }
  175. X    else puts("  No disk present");
  176. X    }
  177. XFreeDAList(&de_head);
  178. XMyprocess->pr_WindowPtr = NULL;
  179. XFreeMem(info,(long)sizeof(struct InfoData));
  180. Xreturn 0;
  181. X}
  182. X
  183. X/* things shared with display_file */
  184. X
  185. XBPTR lastlock;
  186. Xint filecount, col;
  187. Xlong bytes, blocks;
  188. X
  189. X/*
  190. X * the args passed to do_dir will never be expanded
  191. X */
  192. Xdo_dir()
  193. X{
  194. Xint i, c, eac;
  195. Xchar **eav;
  196. X
  197. Xcol = filecount = 0;
  198. Xbytes = blocks = 0L;
  199. Xlastlock=NULL;
  200. X
  201. Xget_opt("sfdcn",&i);
  202. X
  203. Xif (ac == i) { ++ac; av[i]=""; }
  204. Xif (!(options & (DIR_FILES | DIR_DIRS))) options|=(DIR_FILES | DIR_DIRS);
  205. X
  206. Xfor (; i<ac && !CHECKBREAK(); ++i)
  207. X    if (eav = expand(av[i], &eac)) {
  208. X        QuickSort(eav, eac);
  209. X        for(c=0; c<eac && !CHECKBREAK(); ++c)
  210. X            if (options & DIR_NAMES)
  211. X                puts(eav[c]);
  212. X            else
  213. X                display_file(eav[c]);
  214. X        free_expand (eav);
  215. X        }
  216. Xif (col) printf("\n");
  217. Xif (filecount>1) {
  218. X    blocks += filecount; /* account for dir blocks */
  219. X    printf(" %ld Blocks, %ld Bytes used in %d files\n",
  220. X        blocks, bytes, filecount);
  221. X    }
  222. Xif (lastlock) UnLock(lastlock);
  223. Xreturn 0;
  224. X}
  225. X
  226. Xdisplay_file(filestr)
  227. Xchar *filestr;
  228. X{
  229. Xlong atol();
  230. Xint isadir,slen;
  231. Xchar sc, *fi, *base, buf[130];
  232. XBPTR thislock;
  233. X
  234. Xbase=BaseName(filestr);
  235. Xsc = *base;
  236. X*base = '\0';
  237. Xthislock=Lock(filestr,SHARED_LOCK);
  238. X/* if (thislock==NULL) return; */
  239. Xif (lastlock==NULL || CompareLock(thislock,lastlock)) {
  240. X    if (col) printf("\n");
  241. X    col = 0;
  242. X    PathName(thislock, buf, 128L);
  243. X    printf("Directory of %s\n", buf);
  244. X    if (lastlock) UnLock(lastlock);
  245. X    lastlock=thislock;
  246. X    }
  247. Xelse UnLock(thislock);
  248. X*base = sc;
  249. Xslen = strlen(base);
  250. Xfi = base + slen + 1;
  251. Xisadir = (fi[12] =='D');
  252. X
  253. Xif (!(((options & DIR_FILES) && !isadir) ||
  254. X    ((options & DIR_DIRS) &&  isadir)))
  255. X        return;
  256. Xif (isadir && !(options & DIR_NOCOL)) printf ("\23333m");
  257. Xif (options & DIR_SHORT) {
  258. X    if (col==3 && slen>18) { printf("\n"); col = 0; }
  259. X    if (slen>18) { printf(" %-37s",base); col+= 2; }
  260. X        else { printf(" %-18s",base); col++; }
  261. X    if (col > 3) { printf("\n"); col=0; }
  262. X    }
  263. Xelse printf("   %-24s %s",base ,fi);
  264. Xif (isadir && !(options & DIR_NOCOL)) printf("\2330m");
  265. Xfi[16] = fi[21] = '\0';
  266. Xbytes  += atol(fi+10);
  267. Xblocks += atol(fi+17);
  268. Xfilecount++;
  269. X}
  270. X
  271. Xdo_quit()
  272. X{
  273. Xif (Src_stack) {
  274. X    Quit = 1;
  275. X    return(do_return());
  276. X    }
  277. Xmain_exit(0);
  278. X}
  279. X
  280. Xdo_echo()
  281. X{
  282. Xint i;
  283. X
  284. Xget_opt("n",&i);
  285. Xfor ( ; i<ac; i++) {
  286. X    printf("%s", av[i]);
  287. X    if (i != ac-1) printf(" ");
  288. X    }
  289. Xif (!options) printf("\n");
  290. Xreturn 0;
  291. X}
  292. X
  293. X/* gets a line from file, joining two lines if the first ends in '\' */
  294. X
  295. Xchar *myfgets(buf, buflen, file)
  296. Xchar *buf;
  297. XFILE *file;
  298. X{
  299. Xchar *bufptr=buf;
  300. Xint remain=buflen, n, flag;
  301. X
  302. Xdo {
  303. X    if (fgets(bufptr, remain, file)==NULL) {
  304. X        if (remain != buflen)
  305. X            fprintf(stderr,"Source: file ends in '\\'\n");
  306. X        return NULL;
  307. X        }
  308. X    n=strlen(buf);
  309. X    bufptr += n;
  310. X    if (flag= (*(bufptr-2)=='\\')) bufptr-=2;
  311. X    remain -= (n+2);
  312. X    } while (flag);
  313. Xreturn buf;
  314. X}
  315. X
  316. Xdo_source(str)
  317. Xchar *str;
  318. X{
  319. Xregister FILE *fi;
  320. Xchar buf[256];
  321. Xint len;
  322. X
  323. Xif (Src_stack == MAXSRC) {
  324. X    ierror(NULL,217);
  325. X    return -1;
  326. X    }
  327. Xif ((fi = fopen (av[1], "r")) == 0) { pError(av[1]); return -1;    }
  328. Xset_var(LEVEL_SET, v_passed, next_word(next_word(str)));
  329. X++H_stack;
  330. XSrc_pos[Src_stack] = 0;
  331. XSrc_base[Src_stack] = (long)fi;
  332. X++Src_stack;
  333. Xwhile (myfgets (buf, 256, fi) && !dobreak()) {
  334. X    len = strlen(buf);
  335. X    buf[len-1] = '\0';
  336. X    Src_pos[Src_stack - 1] += len;
  337. X    if (Verbose && !forward_goto) fprintf(stderr,"%s\n",buf);
  338. X    exec_command (buf);
  339. X    }
  340. X--H_stack;
  341. X--Src_stack;
  342. Xif (forward_goto) ierror(NULL,501);
  343. Xforward_goto = 0;
  344. Xunset_level(LEVEL_LABEL + Src_stack);
  345. Xunset_var(LEVEL_SET, v_gotofwd);
  346. Xunset_var(LEVEL_SET, v_passed);
  347. Xfclose (fi);
  348. Xreturn 0;
  349. X}
  350. X
  351. X/*
  352. X * set process cwd name and $_cwd, if str != NULL also print it.
  353. X */
  354. Xdo_pwd(str)
  355. Xchar *str;
  356. X{
  357. Xchar pwd[130];
  358. X
  359. XPathName(Myprocess->pr_CurrentDir, pwd, 128L);
  360. Xif (str) puts(pwd);
  361. Xset_var(LEVEL_SET, v_cwd, pwd);
  362. X/* put the current dir name in our CLI task structure */
  363. XCtoBStr(pwd, Mycli->cli_SetName, 128L);
  364. Xreturn 0;
  365. X}
  366. X
  367. X/*
  368. X * CD
  369. X *
  370. X * CD(str, 0)      -do CD operation.
  371. X *
  372. X */
  373. X
  374. Xdo_cd(str)
  375. Xchar *str;
  376. X{
  377. XBPTR oldlock, filelock;
  378. X
  379. Xstr=next_word(str);
  380. Xif (!strcmp("..",str)) str="/";
  381. Xfilelock=Lock(str,ACCESS_READ);
  382. Xif (filelock==NULL) { pError(str); return 20; }
  383. Xif (!isdir(str)) { UnLock(filelock); ierror(str,212); return 20; }
  384. Xif (oldlock=CurrentDir(filelock)) UnLock(oldlock);
  385. Xdo_pwd(NULL);
  386. Xreturn 0;
  387. X}
  388. X
  389. Xdo_mkdir()
  390. X{
  391. Xregister unsigned int i;
  392. XBPTR lock;
  393. X
  394. Xfor (i=1; i<ac; ++i) {
  395. X    if (exists(av[i])) ierror(av[i],203);
  396. X    else if (lock=CreateDir(av[i])) UnLock (lock);
  397. X    else pError(av[i]);
  398. X    }
  399. Xreturn 0;
  400. X}
  401. X
  402. Xdo_mv()
  403. X{
  404. Xchar *dest, buf[256];
  405. Xint dirflag;
  406. Xregister unsigned int i;
  407. X
  408. Xdirflag=isdir(dest=av[--ac]);
  409. Xif (ac>3 && !dirflag) { ierror(dest, 507); return (-1); }
  410. Xfor (i=1; i<ac; ++i) {
  411. X    strcpy(buf, dest);
  412. X    if (dirflag) TackOn(buf, BaseName(av[i]));
  413. X    if (Rename(av[i], buf)==0)
  414. X        { pError(av[i]); return -1; }
  415. X    }
  416. Xreturn 0;
  417. X}
  418. X
  419. Xint dirstoo;
  420. X
  421. Xall_args(args, action, dirsflag)
  422. Xchar *args;
  423. Xint (*action)();
  424. X{
  425. Xunsigned int i;
  426. X
  427. Xget_opt(args, &i);
  428. Xdirstoo=dirsflag;
  429. Xfor (; i<ac && !dobreak(); ++i)
  430. X    if (isdir(av[i])) {
  431. X        if (options & 1) recurse(av[i], action);
  432. X            else if (dirstoo) (*action)(av[i]);
  433. X        }
  434. X    else (*action)(av[i]);
  435. Xreturn 0;
  436. X}
  437. X
  438. Xchar *searchstring;
  439. X
  440. Xsearch_file(s)
  441. Xchar *s;
  442. X{
  443. XFILE *fopen(), *fi;
  444. Xregister char *p;
  445. Xregister unsigned int
  446. X    nocasedep, lctr, len, excl=((options & 16) !=0 ), yesno;
  447. Xchar buf[256], lowbuf[256], searchit[256], first;
  448. X
  449. Xif (strcmp("STDIN",s)) fi=fopen(s,"r"); else fi=stdin;
  450. Xif (fi==NULL) { pError(s); return; }
  451. Xnocasedep=!(options & 2);
  452. Xlctr=0;
  453. Xif (!(options & 32)) printf("Examining %s...\n",s);
  454. Xstrcpy(searchit,searchstring);
  455. Xif (options & 4) strcat(searchit,"\n");
  456. Xlen=strlen(searchit);
  457. Xif (nocasedep) strupr(searchit);
  458. Xfirst=*searchit;
  459. Xwhile (fgets(buf,256,fi) && !dobreak()) {
  460. X    lctr++;
  461. X    if (options & 4) yesno=compare_ok(searchit, buf, options & 2);
  462. X    else {
  463. X        if (nocasedep) {
  464. X            strcpy(lowbuf,buf);
  465. X            strupr(lowbuf);
  466. X            p=lowbuf;
  467. X            }
  468. X        else p=buf;
  469. X        while ((p=index(p,first)) && strncmp(p++,searchit,len)) ;
  470. X        yesno= (p!=NULL);
  471. X        }
  472. X    if (yesno ^ excl) {
  473. X            /* default: print line numbers */
  474. X        if (!(options & 8)) printf("%4d ",lctr);
  475. X        printf("%s",buf);
  476. X        }
  477. X    }
  478. Xif (fi!=stdin) fclose (fi);
  479. X}
  480. X
  481. Xdo_search()
  482. X{
  483. Xsearchstring=av[--ac];
  484. Xall_args("rcwneq", search_file, 0);
  485. Xreturn 0;
  486. X}
  487. X
  488. Xrm_file(file)
  489. Xchar *file;
  490. X{
  491. Xif (has_wild) printf(" %s...",file);
  492. Xif (options & 2) SetProtection(file,0L);
  493. Xif (!DeleteFile(file)) pError (file); else if (has_wild) printf("Deleted\n");
  494. X}
  495. X
  496. Xdo_rm()
  497. X{
  498. Xall_args("rp", rm_file, 1);
  499. Xreturn 0;
  500. X}
  501. X
  502. Xrecurse(name, action)
  503. Xchar *name;
  504. Xint (*action)();
  505. X{
  506. Xregister BPTR lock, cwd;
  507. Xregister FIB *fib=(FIB *)AllocMem((long)sizeof(FIB),MEMF_PUBLIC);
  508. Xchar *namecopy=malloc(256);
  509. X
  510. Xif (name[0] =='\0') return;
  511. Xnamecopy[0]=0;
  512. Xif (lock=Lock(name,ACCESS_READ)) {
  513. X    cwd =CurrentDir(lock);
  514. X    if (Examine(lock, fib))
  515. X    while (ExNext(lock, fib) && !CHECKBREAK()) {
  516. X        if (*namecopy) { (*action)(namecopy); namecopy[0]=0; }
  517. X        if (fib->fib_DirEntryType>=0) recurse(fib->fib_FileName,action);
  518. X        else strcpy(namecopy,fib->fib_FileName);
  519. X        }
  520. X    if (*namecopy) (*action)(namecopy);
  521. X    UnLock(CurrentDir(cwd));
  522. X    if (dirstoo) (*action)(name);
  523. X    }
  524. Xelse pError(name);
  525. Xfree(namecopy);
  526. XFreeMem(fib, (long)sizeof(FIB));
  527. X}
  528. X
  529. Xdo_history()
  530. X{
  531. Xregister struct HIST *hist;
  532. Xint i = H_tail_base;
  533. Xint len = (av[1]) ? strlen(av[1]) : 0;
  534. X
  535. Xfor (hist = H_tail; hist && !dobreak(); hist = hist->prev)
  536. X    if (len == 0 || !strncmp(av[1], hist->line, len))
  537. X        printf("%3d %s\n", i++, hist->line);
  538. Xreturn 0;
  539. X}
  540. X
  541. Xdo_mem()
  542. X{
  543. Xlong cfree, ffree;
  544. Xextern long AvailMem();
  545. X
  546. XForbid();
  547. Xcfree = AvailMem (MEMF_CHIP);
  548. Xffree = AvailMem (MEMF_FAST);
  549. XPermit();
  550. Xif (ffree) printf ("FAST memory: %ld\nCHIP memory: %ld\n", ffree, cfree);
  551. Xprintf("Total  Free: %ld\n", cfree+ffree);
  552. Xreturn 0;
  553. X}
  554. X
  555. Xdo_forline()
  556. X{
  557. Xchar vname[33], buf[256];
  558. Xregister unsigned short lctr;
  559. XFILE *f;
  560. Xchar *cstr;
  561. X
  562. Xstrcpy(vname,av[1]);
  563. Xf=fopen(av[2],"r");
  564. Xif (f==NULL) pError(av[2]);
  565. Xlctr=0;
  566. X++H_stack;
  567. Xcstr = compile_av (av, 3, ac, ' ', 0);
  568. Xwhile (fgets(buf,256,f) && !dobreak()) {
  569. X    buf[strlen(buf)-1]='\0';    /* remove CR */
  570. X    lctr++;
  571. X    set_var(LEVEL_SET, vname, buf);
  572. X    sprintf(buf,"%d",lctr);
  573. X    set_var(LEVEL_SET, v_linenum, buf);
  574. X    exec_command(cstr);
  575. X    }
  576. Xfclose(f);
  577. X--H_stack;
  578. Xfree (cstr);
  579. Xunset_var (LEVEL_SET, vname);
  580. Xunset_var (LEVEL_SET, v_linenum);
  581. Xreturn 0;
  582. X}
  583. X
  584. Xdo_fornum()
  585. X{
  586. Xchar vname[33], buf[16];
  587. Xint n1, n2, step, i, verbose;
  588. Xchar *cstr;
  589. X
  590. Xget_opt("vs",&i);
  591. Xverbose=(options & 1);
  592. Xstrcpy(vname,av[i++]);
  593. Xn1=myatoi(av[i++],-32767,32767); if (atoierr) return 20;
  594. Xn2=myatoi(av[i++],-32767,32767); if (atoierr) return 20;
  595. Xif (options & 2) {
  596. X    step=myatoi(av[i++],-32767,32767); if (atoierr) return 20;
  597. X    }
  598. Xelse
  599. X    step=1;
  600. X++H_stack;
  601. Xcstr = compile_av (av, i, ac, ' ', 0);
  602. Xfor (i=n1; (step>=0 ? i<=n2 : i>=n2) && !CHECKBREAK(); i+=step) {
  603. X    if (verbose) fprintf(stderr, "fornum: %d\n", i);
  604. X    sprintf(buf,"%d",i);
  605. X    set_var (LEVEL_SET, vname, buf);
  606. X    exec_command(cstr);
  607. X    }
  608. X--H_stack;
  609. Xfree (cstr);
  610. Xunset_var (LEVEL_SET, vname);
  611. Xreturn 0;
  612. X}
  613. X
  614. X/*
  615. X * foreach var_name  ( str str str str... str ) commands
  616. X * spacing is important (unfortunately)
  617. X *
  618. X * ac=0    1 2 3 4 5 6 7
  619. X * foreach i ( a b c ) echo $i
  620. X * foreach i ( *.c ) "echo -n "file ->";echo $i"
  621. X */
  622. X
  623. Xdo_foreach()
  624. X{
  625. Xregister int cstart, cend;
  626. Xregister char *cstr;
  627. Xchar **fav;
  628. Xchar vname[33];
  629. Xint i, verbose;
  630. X
  631. Xget_opt("v",&i);
  632. Xverbose=(options & 1);
  633. Xstrcpy(vname, av[i++]);
  634. Xif (*av[i] == '(') i++;
  635. Xcstart = i;
  636. Xwhile (i<ac && *av[i] != ')') i++;
  637. Xif (i > ac) { fprintf(stderr,"')' expected\n"); return 20; }
  638. X++H_stack;
  639. Xcend = i;
  640. X
  641. Xfav = (char **)malloc(sizeof(char *) * (ac));
  642. Xcstr = compile_av (av, cend + 1, ac, ' ', 0);
  643. X
  644. Xfor (i = cstart; i < cend; ++i) fav[i] = av[i];
  645. X
  646. Xfor (i = cstart; i<cend && !CHECKBREAK(); ++i) {
  647. X    set_var (LEVEL_SET, vname, fav[i]);
  648. X    if (verbose) fprintf(stderr, "foreach: %s\n", fav[i]);
  649. X    exec_command(cstr);
  650. X    }
  651. X--H_stack;
  652. Xfree (fav);
  653. Xfree (cstr);
  654. Xunset_var (LEVEL_SET, vname);
  655. Xreturn 0;
  656. X}
  657. X
  658. Xdo_forever(str)
  659. Xchar *str;
  660. X{
  661. Xint rcode = 0;
  662. Xchar *ptr = next_word(str);
  663. X
  664. X++H_stack;
  665. Xfor (;;) {
  666. X    if (CHECKBREAK()) { rcode = 20; break; }
  667. X    if (exec_command (ptr) < 0) {
  668. X        str = get_var(LEVEL_SET, v_lasterr);
  669. X        rcode = (str) ? atoi(str) : 20;
  670. X        break;
  671. X        }
  672. X    }
  673. X--H_stack;
  674. Xreturn rcode;
  675. X}
  676. X
  677. Xdo_exec(str)
  678. Xchar *str;
  679. X{
  680. Xreturn exec_command(next_word(str));
  681. X}
  682. X
  683. Xextern struct Window *w;
  684. Xextern struct IntuitionBase *IntuitionBase;
  685. X
  686. Xdo_window()
  687. X{
  688. Xlong x, y, maxwidth, maxheight, arg[5];
  689. Xunsigned int i;
  690. Xstruct Screen *screen;
  691. Xstruct Window *window;
  692. X
  693. Xget_opt("slfbaq", &i);
  694. Xif (options & 1)
  695. X    SizeWindow(w, (long)(w->MinWidth-w->Width), (long)(w->MinHeight-w->Height));
  696. Xif (options & 2) {
  697. X    x=-w->LeftEdge;
  698. X    y=-w->TopEdge;
  699. X    MoveWindow(w,x,y);
  700. X    x=IntuitionBase->ActiveScreen->Width -w->Width;
  701. X    y=IntuitionBase->ActiveScreen->Height-w->Height;
  702. X    SizeWindow(w,x,y);
  703. X    }
  704. Xif (options & 4) WindowToFront(w);
  705. Xif (options & 8) WindowToBack(w);
  706. Xif (options & 16) ActivateWindow(w);
  707. Xif(ac >= 5) {
  708. X    for(i=1; i<5; i++) {
  709. X        arg[i] = myatoi(av[i],0,1023); if (atoierr) return 20;
  710. X        }
  711. X    maxwidth = w->WScreen->Width;
  712. X    maxheight= w->WScreen->Height;
  713. X    if (arg[3] > maxwidth - arg[1] || arg[4] > maxheight- arg[2]) {
  714. X        ierror(NULL, 500);
  715. X        return 20;
  716. X        }
  717. X    x = -w->LeftEdge;
  718. X    y = -w->TopEdge;
  719. X    MoveWindow(w, x, y);
  720. X    x = arg[3] - w->Width;
  721. X    y = arg[4] - w->Height;
  722. X    SizeWindow(w, x, y);
  723. X    x = arg[1];
  724. X    y = arg[2];
  725. X    MoveWindow(w, x, y);
  726. X    }
  727. Xif(options & 32) {
  728. X    for (screen=IntuitionBase->FirstScreen; screen; screen=screen->NextScreen) {
  729. X        printf("\nScreen \"%s\" (%d,%d,%dx%d):\n",
  730. X            screen->Title,
  731. X            screen->LeftEdge,
  732. X            screen->TopEdge,
  733. X            screen->Width,
  734. X            screen->Height
  735. X            );
  736. X        for (window=screen->FirstWindow; window; window=window->NextWindow) {
  737. X        printf("\tWindow\t\"%s\" (%d,%d,%dx%d)\n",
  738. X            window->Title,
  739. X            window->LeftEdge,
  740. X            window->TopEdge,
  741. X            window->Width,
  742. X            window->Height
  743. X            );
  744. X        }
  745. X        }
  746. X    return 0;
  747. X    }
  748. XDelay(25L); /* pause 1/2 sec. before trying to print */
  749. Xprintf("\014");
  750. Xreturn 0;
  751. X}
  752. X
  753. Xsetsystemtime(ds)
  754. Xstruct DateStamp *ds;
  755. X{
  756. Xstruct timerequest tr;
  757. Xlong secs= ds->ds_Days*86400 + ds->ds_Minute*60 + ds->ds_Tick/TICKS_PER_SECOND;
  758. X
  759. Xif (OpenDevice(TIMERNAME, UNIT_VBLANK, &tr, 0L)) {
  760. X    fprintf(stderr,"Clock error: can't open timer device\n");
  761. X    return;
  762. X    }
  763. Xtr.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE;
  764. Xtr.tr_node.io_Message.mn_Node.ln_Pri = 0L;
  765. Xtr.tr_node.io_Message.mn_Node.ln_Name = NULL;
  766. Xtr.tr_node.io_Message.mn_ReplyPort = NULL;
  767. Xtr.tr_node.io_Command = TR_SETSYSTIME;
  768. Xtr.tr_time.tv_secs = secs;
  769. Xtr.tr_time.tv_micro = 0L;
  770. Xif (DoIO (&tr)) fprintf(stderr,"Clock error: can't talk to timer device\n");
  771. XCloseDevice (&tr);
  772. X}
  773. X
  774. Xchar tday[10];
  775. X
  776. Xchar *dates(dss)
  777. Xstruct DateStamp *dss;
  778. X{
  779. Xstatic char timestr[40];
  780. Xchar tdate[10], ttime[10];
  781. Xstruct DateTime dt;
  782. Xstruct DateStamp *myds=&(dt.dat_Stamp);
  783. X
  784. Xdt.dat_Format=FORMAT_DOS;
  785. Xdt.dat_StrDay=tday;
  786. Xdt.dat_StrDate=tdate;
  787. Xdt.dat_StrTime=ttime;
  788. Xdt.dat_Flags=NULL;
  789. Xmyds->ds_Days=dss->ds_Days;
  790. Xmyds->ds_Minute=dss->ds_Minute;
  791. Xmyds->ds_Tick=dss->ds_Tick;
  792. XStamptoStr(&dt);
  793. Xsprintf(timestr,"%s %s\n",tdate,ttime);
  794. Xtimestr[18]='\n';
  795. Xtimestr[19]='\0';    /* protection against bad timestamped files */
  796. Xreturn timestr;
  797. X}
  798. X
  799. Xdo_date()
  800. X{
  801. Xstruct DateStamp dss;
  802. Xregister unsigned short i;
  803. Xstruct DateTime dt;
  804. X
  805. Xdt.dat_Format=FORMAT_DOS;
  806. Xif (ac==1) {
  807. X    DateStamp(&dss);
  808. X    printf("%s %s",tday,dates(&dss));
  809. X    }
  810. Xelse {
  811. X    DateStamp(& (dt.dat_Stamp));
  812. X    for (i=1; i<ac; i++) {
  813. X        dt.dat_StrDate=NULL;
  814. X        dt.dat_StrTime=NULL;
  815. X        dt.dat_Flags=DTF_FUTURE;
  816. X        if (index(av[i],':')) dt.dat_StrTime=av[i];
  817. X            else dt.dat_StrDate=av[i];
  818. X        if (StrtoStamp(&dt)) ierror(av[i],500);
  819. X        }
  820. X    setsystemtime( & (dt.dat_Stamp) );
  821. X    }
  822. Xreturn 0;
  823. X}
  824. END_OF_FILE
  825. if test 16508 -ne `wc -c <'comm1.c'`; then
  826.     echo shar: \"'comm1.c'\" unpacked with wrong size!
  827. fi
  828. # end of 'comm1.c'
  829. fi
  830. if test -f 'comm2.c' -a "${1}" != "-c" ; then 
  831.   echo shar: Will not clobber existing file \"'comm2.c'\"
  832. else
  833. echo shar: Extracting \"'comm2.c'\" \(13095 characters\)
  834. sed "s/^X//" >'comm2.c' <<'END_OF_FILE'
  835. X/*
  836. X * COMM2.C
  837. X *
  838. X * (c)1986 Matthew Dillon     9 October 1986
  839. X *
  840. X * Version 2.07M by Steve Drew 10-Sep-87
  841. X *
  842. X * Version 4.00A by Carlo Borreo & Cesare Dieni 13-Jan-90
  843. X *
  844. X */
  845. X
  846. X/* Casting conveniences */
  847. X#define BPTR_TO_C(strtag, var)  ((struct strtag *)(BADDR( (ULONG) var)))
  848. X#define PROC(task)              ((struct Process *)task)
  849. X#define CLI(proc)               (BPTR_TO_C(CommandLineInterface, proc->pr_CLI))
  850. X
  851. X/* Externs */
  852. Xextern int has_wild;                    /* flag set if any arg has a ? or * */
  853. X
  854. X/* globals */
  855. Xint cp_update;
  856. Xint cp_date;
  857. X
  858. Xdo_abortline()
  859. X{
  860. XExec_abortline = 1;
  861. Xreturn 0;
  862. X}
  863. X
  864. Xdo_return()
  865. X{
  866. Xregister int retcode=(ac<2 ? 0 : atoi(av[1]));
  867. X   Exec_abortline = 1;
  868. X   if (Src_stack) {
  869. X       FILE *ptr = (FILE *)Src_base[Src_stack - 1];
  870. X       ptr->_bp = ptr->_bend;
  871. X       ptr->_flags |= _EOF;
  872. X/*     fseek (Src_base[Src_stack - 1], 0L, 2); */
  873. X      return retcode;
  874. X   } else main_exit(retcode);
  875. X}
  876. X
  877. X/*
  878. X * STRHEAD
  879. X *
  880. X * place a string into a variable removing everything after and including
  881. X * the 'break' character
  882. X *
  883. X * strhead varname breakchar string
  884. X *
  885. X */
  886. X
  887. Xdo_strhead()
  888. X{
  889. Xchar *s;
  890. Xif (s=index(av[3],*av[2])) *s='\0';
  891. Xset_var (LEVEL_SET, av[1], av[3]);
  892. Xreturn 0;
  893. X}
  894. X
  895. Xdo_strtail()
  896. X{
  897. Xchar *s;
  898. Xif (s=index(av[3],*av[2])) s++; else s=av[3];
  899. Xset_var (LEVEL_SET, av[1], s);
  900. Xreturn 0;
  901. X}
  902. X
  903. Xlong dptrtosecs(d)
  904. Xstruct DPTR *d;
  905. X{
  906. Xregister struct DateStamp *ds=(&d->fib->fib_Date);
  907. Xreturn ds->ds_Days*86400 + ds->ds_Minute*60 + ds->ds_Tick/TICKS_PER_SECOND;
  908. X}
  909. X
  910. Xlong timeof(s)
  911. Xchar *s;
  912. X{
  913. Xstruct DPTR *d;
  914. Xint dummy;
  915. Xlong n;
  916. X
  917. Xif ( (d=dopen(s,&dummy))==NULL ) return 0L;
  918. Xn=dptrtosecs(d);
  919. Xdclose(d);
  920. Xreturn n;
  921. X}
  922. X
  923. X/*
  924. X * if -f file (exists) or:
  925. X *
  926. X * if A < B   <, >, =, <=, >=, <>, where A and B are either:
  927. X * nothing
  928. X * a string
  929. X * a value (begins w/ number)
  930. X */
  931. X
  932. Xdo_if(garbage, com)
  933. Xchar *garbage;
  934. X{
  935. Xint result;
  936. Xint i;
  937. X
  938. Xswitch (com) {
  939. X    case 0:
  940. X    if (If_stack && If_base[If_stack - 1]) If_base[If_stack++] = 1;
  941. X    else {
  942. X        get_opt("rftmdvn",&i);
  943. X        result=evalif(i);
  944. X        If_base[If_stack++]=(options & 64 ? result : !result);
  945. X        }
  946. X    break;
  947. X    case 1:
  948. X    if (If_stack > 1 && If_base[If_stack - 2]) break;
  949. X    if (If_stack) If_base[If_stack - 1] ^= 1;
  950. X    break;
  951. X    case 2:
  952. X    if (If_stack) --If_stack;
  953. X    break;
  954. X     }
  955. Xdisable = (If_stack) ? If_base[If_stack - 1] : 0;
  956. Xif (If_stack >= MAXIF) {
  957. X    fprintf(stderr,"If's too deep\n");
  958. X    disable = If_stack = 0;
  959. X    return -1;
  960. X    }
  961. Xif (forward_goto) disable = If_base[If_stack - 1] = 0;
  962. Xreturn 0;
  963. X}
  964. X
  965. Xevalif(i)
  966. Xregister unsigned int i;
  967. X{
  968. Xchar c;
  969. Xlong num, t0, isint;
  970. Xlong AvailMem();
  971. X
  972. Xswitch(options & ~64) {
  973. X    case 0:
  974. X    if (ac-i != 3) return (ac>i && *av[i]);
  975. X    num  = Atol(av[i]);
  976. X    isint  = ! IoErr();
  977. X    num -= Atol(av[i+2]);
  978. X    isint &= ! IoErr();
  979. X    if (!isint) num=strcmp(av[i],av[i+2]);
  980. X    if (num < 0)       c='<';
  981. X    else if (num > 0)  c='>';
  982. X    else if (num == 0) c='=';
  983. X    return index(av[i+1], c) != NULL;
  984. X    case 1:
  985. X    return do_rpn(NULL,i);
  986. X    case 2:
  987. X    return exists(av[i]);
  988. X    case 4:
  989. X    t0=timeof(av[i++]);
  990. X    for ( ; i<ac ; i++)
  991. X        if (t0<=timeof(av[i])) return 1;
  992. X    return 0;
  993. X    case 8:
  994. X    return (AvailMem( (long)MEMF_FAST )!=0);
  995. X    case 16:
  996. X    return (isdir(av[i])!=0);
  997. X    case 32:
  998. X    return (get_var(LEVEL_SET,av[i]) != 0);
  999. X    default:
  1000. X    ierror(NULL,500);
  1001. X    return 0;
  1002. X    }
  1003. X}
  1004. X
  1005. Xdo_label()
  1006. X{
  1007. X   char aseek[32];
  1008. X
  1009. X   if (Src_stack == 0) {
  1010. X      ierror (NULL, 502);
  1011. X      return (-1);
  1012. X   }
  1013. X
  1014. X   sprintf (aseek, "%ld %d", Src_pos[Src_stack-1], If_stack);
  1015. X   set_var (LEVEL_LABEL + Src_stack - 1, av[1], aseek);
  1016. X   if (!strcmp(av[1],get_var(LEVEL_SET,v_gotofwd)))
  1017. X      forward_goto = 0;
  1018. X   return 0;
  1019. X}
  1020. X
  1021. Xdo_goto()
  1022. X{
  1023. X   int new;
  1024. X   long pos;
  1025. X   char *lab;
  1026. X
  1027. X   if (Src_stack == 0) {
  1028. X      ierror (NULL, 502);
  1029. X   } else {
  1030. X      lab = get_var (LEVEL_LABEL + Src_stack - 1, av[1]);
  1031. X      if (lab == NULL) {
  1032. X         forward_goto = 1;
  1033. X         set_var (LEVEL_SET, v_gotofwd, av[1]);
  1034. X         return(0);
  1035. X      } else {
  1036. X         pos = atoi(lab);
  1037. X         fseek (Src_base[Src_stack - 1], pos, 0);
  1038. X         Src_pos[Src_stack - 1] = pos;
  1039. X         new = atoi(next_word(lab));
  1040. X         for (; If_stack < new; ++If_stack)
  1041. X            If_base[If_stack] = 0;
  1042. X         If_stack = new;
  1043. X      }
  1044. X   }
  1045. X   Exec_abortline = 1;
  1046. X   return (0);      /* Don't execute rest of this line */
  1047. X}
  1048. X
  1049. X
  1050. Xdo_inc(garbage, com)
  1051. Xchar *garbage;
  1052. X{
  1053. Xchar *var, num[32];
  1054. X
  1055. Xif (ac>2) com *= atoi(av[2]);
  1056. Xif (var = get_var (LEVEL_SET, av[1])) {
  1057. X    sprintf (num, "%d", atoi(var)+com);
  1058. X    set_var (LEVEL_SET, av[1], num);
  1059. X    }
  1060. Xreturn 0;
  1061. X}
  1062. X
  1063. Xdo_input()
  1064. X{
  1065. Xchar in[256], *p,*s;
  1066. Xunsigned int i;
  1067. X
  1068. Xfor (i=1; i < ac; ++i)
  1069. X    if (gets(in)) {
  1070. X    for(p = in; *p; p = s) {
  1071. X        s = next_word(p);
  1072. X        if (*s) *(s-1) = 0xA0;
  1073. X        }
  1074. X    set_var (LEVEL_SET, av[i], in);
  1075. X    }
  1076. Xreturn 0;
  1077. X}
  1078. X
  1079. Xdo_ver()
  1080. X{
  1081. Xextern char shellname[];
  1082. X
  1083. Xputs(shellname);
  1084. Xputs("(c)1986 Matthew Dillon\n\
  1085. XManx (M) versions by Steve Drew\n\
  1086. XARP (A) versions by Carlo Borreo & Cesare Dieni\n");
  1087. Xreturn 0;
  1088. X}
  1089. X
  1090. Xdo_ps()
  1091. X{
  1092. X/* this code fragment based on ps.c command by Dewi Williams */
  1093. X
  1094. Xregister int    count;        /* loop variable        */
  1095. Xstruct Task    *task;        /* EXEC descriptor        */
  1096. Xchar        strbuf[64+1];    /* scratch for btocstr()    */
  1097. Xchar        cmd[40+1];    /* holds cmd name        */
  1098. Xlong ncli;
  1099. X
  1100. Xprintf("Proc Command Name         CLI Type    Pri.  Address  Directory\n");
  1101. XForbid();
  1102. X
  1103. Xncli=(long)FindCLI(0L);
  1104. Xfor (count = 1; count <= ncli ; count++)
  1105. X        /* or just assume 20?*/
  1106. X    if (task = (struct Task *)FindCLI((long)count)) {
  1107. X    if (task==NULL) continue;
  1108. X    /* Sanity check just in case */
  1109. X    if (PROC(task)->pr_TaskNum == 0 || PROC(task)->pr_CLI == 0) continue;
  1110. X                            /* or complain? */
  1111. X    BtoCStr(cmd,   CLI(PROC(task))->cli_CommandName, 40L);
  1112. X    BtoCStr(strbuf,CLI(PROC(task))->cli_SetName    , 64L);
  1113. X    printf("%2d   %-20.20s %-11.11s %3d  %8lx  %s\n",
  1114. X        count,
  1115. X        cmd,
  1116. X        task->tc_Node.ln_Name,
  1117. X        task->tc_Node.ln_Pri,
  1118. X        task,
  1119. X        strbuf);
  1120. X    }
  1121. XPermit();
  1122. Xreturn 0;
  1123. X}
  1124. X
  1125. X/*
  1126. X * CP [-d] [-u] file file
  1127. X * CP [-d] [-u] file file file... destdir
  1128. X * CP [-r][-u][-d] dir dir dir... destdir
  1129. X */
  1130. X
  1131. Xchar *errstr;          /* let's be alittle more informative */
  1132. X
  1133. Xdo_copy()
  1134. X{
  1135. Xregister int recur, ierr;
  1136. Xregister char *destname;
  1137. Xregister char destisdir;
  1138. Xregister FIB *fib;
  1139. Xint i;
  1140. X
  1141. Xerrstr = "";
  1142. Xierr = 0;
  1143. X
  1144. Xfib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  1145. X
  1146. Xget_opt("rud",&i);
  1147. Xrecur     = (options & 0x01);
  1148. Xcp_update = (options & 0x02);
  1149. Xcp_date   = (!(options & 0x04)); /* the default is keep orignal file date */
  1150. X
  1151. Xdestname = av[ac - 1];
  1152. X
  1153. Xif (ac < i + 2) {
  1154. X    ierr = 500;
  1155. X    goto done;
  1156. X    }
  1157. Xdestisdir = isdir(destname);
  1158. Xif (ac > i + 2 && !destisdir) {
  1159. X    ierr = 507;
  1160. X    goto done;
  1161. X    }
  1162. X
  1163. X/*
  1164. X * copy set:                        reduce to:
  1165. X *    file to file                     file to file
  1166. X *    dir  to file (NOT ALLOWED)
  1167. X *    file to dir                      dir to dir
  1168. X *    dir  to dir                      dir to dir
  1169. X *
  1170. X */
  1171. X
  1172. Xfor (; i<ac-1 && !dobreak(); ++i) {
  1173. X    short srcisdir = isdir(av[i]);
  1174. X    if (srcisdir && has_wild && (ac >2)) /* hack to stop dir's from */
  1175. X        continue;             /* getting copied if specified */
  1176. X                         /* from wild expansion */
  1177. X    if (srcisdir) {
  1178. X        BPTR srcdir, destdir;
  1179. X        if (!destisdir) {
  1180. X            if (exists(destname)) {
  1181. X                ierr = 507;    /* disallow dir to file */
  1182. X                goto done;
  1183. X                }
  1184. X            if (destdir = CreateDir(destname)) UnLock(destdir);
  1185. X            destisdir = 1;
  1186. X            }
  1187. X        if (!(destdir = Lock(destname, ACCESS_READ))) {
  1188. X            ierr = 205;
  1189. X            errstr = destname;
  1190. X            goto done;
  1191. X            }
  1192. X        if (!(srcdir = Lock(av[i], ACCESS_READ))) {
  1193. X            ierr = 205;
  1194. X            errstr = av[i];
  1195. X            UnLock(destdir);
  1196. X            goto done;
  1197. X            }
  1198. X        ierr = copydir(srcdir, destdir, recur);
  1199. X        UnLock(srcdir);
  1200. X        UnLock(destdir);
  1201. X        if (ierr) break;
  1202. X        }
  1203. X    else {        /* FILE to DIR,   FILE to FILE   */
  1204. X        BPTR destdir, srcdir, tmp;
  1205. X        char *destfilename;
  1206. X
  1207. X        srcdir = (BPTR)(Myprocess->pr_CurrentDir);
  1208. X
  1209. X        if ((tmp = Lock(av[i], ACCESS_READ)) == NULL || !Examine(tmp,fib)) {
  1210. X            if (tmp) UnLock(tmp);
  1211. X            ierr = 205;
  1212. X            errstr = av[i];
  1213. X            goto done;
  1214. X            }
  1215. X        UnLock(tmp);
  1216. X        if (destisdir) {
  1217. X            destdir = Lock(destname, ACCESS_READ);
  1218. X            destfilename = fib->fib_FileName;
  1219. X            }
  1220. X        else {
  1221. X            destdir = srcdir;
  1222. X            destfilename = destname;
  1223. X            }
  1224. X        printf(" %s..",av[i]);
  1225. X        fflush(stdout);
  1226. X        ierr = copyfile(av[i], srcdir, destfilename, destdir);
  1227. X        if (destisdir) UnLock(destdir);
  1228. X        if (ierr) break;
  1229. X        }
  1230. X    }
  1231. X
  1232. Xdone:
  1233. X
  1234. XFreeMem(fib, (long)sizeof(FIB));
  1235. Xif (ierr) {
  1236. X    ierror(errstr, ierr);
  1237. X    return(20);
  1238. X    }
  1239. Xreturn 0;
  1240. X}
  1241. X
  1242. X
  1243. Xcopydir(srcdir, destdir, recur)
  1244. Xregister BPTR srcdir, destdir;
  1245. X{
  1246. X   BPTR cwd;
  1247. X   register FIB *srcfib;
  1248. X   register BPTR destlock, srclock;
  1249. X   int ierr;
  1250. X   static int level;
  1251. X
  1252. X   level++;
  1253. X   ierr = 0;
  1254. X   srcfib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  1255. X   if (Examine(srcdir, srcfib)) {
  1256. X      while (ExNext(srcdir, srcfib)) {
  1257. X         if (CHECKBREAK())
  1258. X            break;
  1259. X         if (srcfib->fib_DirEntryType < 0) {
  1260. X            printf("%*s%s..",(level-1) * 6," ",srcfib->fib_FileName);
  1261. X            fflush(stdout);
  1262. X            ierr = copyfile(srcfib->fib_FileName,srcdir,srcfib->fib_FileName,destdir);
  1263. X            if (ierr)
  1264. X               break;
  1265. X         } else {
  1266. X            if (recur) {
  1267. X               cwd = CurrentDir(srcdir);
  1268. X               if (srclock = Lock(srcfib->fib_FileName, ACCESS_READ)) {
  1269. X                  CurrentDir(destdir);
  1270. X                  if (!(destlock = Lock(srcfib->fib_FileName, ACCESS_WRITE))) {
  1271. X                     destlock = CreateDir(srcfib->fib_FileName);
  1272. X                     printf("%*s%s (Dir)....[Created]\n",(level-1) * 6,
  1273. X                                " ",srcfib->fib_FileName);
  1274. X
  1275. X                        /* UnLock and re Lock if newly created
  1276. X                           for file_date() to work properly
  1277. X                        */
  1278. X                     if (destlock) UnLock(destlock);
  1279. X                     destlock = Lock(srcfib->fib_FileName, ACCESS_WRITE);
  1280. X                  }
  1281. X                  else
  1282. X                     printf("%*s%s (Dir)\n",(level-1) * 6," ",srcfib->fib_FileName);
  1283. X                  if (destlock) {
  1284. X                     ierr = copydir(srclock, destlock, recur);
  1285. X                     UnLock(destlock);
  1286. X                  } else {
  1287. X                     ierr = (int)((long)IoErr());
  1288. X                  }
  1289. X                  UnLock(srclock);
  1290. X               } else {
  1291. X                  ierr = (int)((long)IoErr());
  1292. X               }
  1293. X               CurrentDir(cwd);
  1294. X               if (ierr)
  1295. X                  break;
  1296. X            }
  1297. X         }
  1298. X      }
  1299. X   } else {
  1300. X      ierr = (int)((long)IoErr());
  1301. X   }
  1302. X   --level;
  1303. X   FreeMem(srcfib, (long)sizeof(FIB));
  1304. X   return(ierr);
  1305. X}
  1306. X
  1307. X
  1308. Xcopyfile(srcname, srcdir, destname, destdir)
  1309. Xchar *srcname, *destname;
  1310. XBPTR srcdir, destdir;
  1311. X{
  1312. XBPTR cwd;
  1313. XBPTR f1, f2;
  1314. Xlong i;
  1315. Xint stat,ierr;
  1316. Xchar *buf;
  1317. Xstruct DPTR *dp, *dps = NULL;
  1318. X
  1319. Xif ((buf = (char *)AllocMem(8192L, MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  1320. X    { ierr = 103; goto fail; }
  1321. Xierr = 0;
  1322. Xcwd = CurrentDir(srcdir);
  1323. Xif ((f1=Open(srcname, MODE_OLDFILE))==NULL)
  1324. X    { errstr = srcname; ierr = 205; goto fail; }
  1325. Xdps = dopen(srcname,&stat);
  1326. XCurrentDir(destdir);
  1327. Xif (cp_update)
  1328. X    {
  1329. X    dp=dopen(destname, &stat);
  1330. X    if ( dptrtosecs(dp) >= dptrtosecs(dps) &&
  1331. X        !strcmp(dps->fib->fib_FileName, dp->fib->fib_FileName))
  1332. X        { dclose(dp); Close(f1); printf("..not newer\n"); goto fail; }
  1333. X    dclose(dp);
  1334. X    }
  1335. Xif ((f2=Open(destname, MODE_NEWFILE))==NULL)
  1336. X    { Close(f1); ierr = (int)((long)IoErr()); errstr=destname; goto fail;  }
  1337. Xwhile (i = Read(f1, buf, 8192L))
  1338. X    if (Write(f2, buf, i) != i) { ierr = (int)((long)IoErr()); break; }
  1339. XClose(f2);
  1340. XClose(f1);
  1341. Xif (!ierr)
  1342. X    {
  1343. X    if (cp_date) file_date(&dps->fib->fib_Date, destname);
  1344. X    printf("..copied\n");
  1345. X    }
  1346. Xelse DeleteFile(destname);
  1347. Xfail:
  1348. X dclose(dps);
  1349. X if (buf) FreeMem(buf, 8192L);
  1350. X CurrentDir(cwd);
  1351. X return(ierr);
  1352. X}
  1353. X
  1354. Xdo_touch()
  1355. X{
  1356. Xstruct DateStamp ds;
  1357. Xregister unsigned int i;
  1358. XDateStamp(&ds);
  1359. Xfor (i=1; i<ac; i++) if (file_date(&ds, av[i])) ierror(av[i],500);
  1360. Xreturn 0;
  1361. X}
  1362. X
  1363. Xfile_date(date,name)
  1364. Xstruct DateStamp *date;
  1365. Xchar *name;
  1366. X{
  1367. Xlong packargs[7];
  1368. XUBYTE *ptr;
  1369. Xstruct MsgPort *task;
  1370. XBPTR dirlock;
  1371. Xstruct DPTR *tmp;
  1372. Xint stat;
  1373. X
  1374. Xif (!(task = (struct MsgPort *)DeviceProc(name))) return(1);
  1375. Xif (tmp = dopen(name, &stat)) {
  1376. X    dirlock = ParentDir(tmp->lock);
  1377. X    ptr=AllocMem(65L,MEMF_PUBLIC);
  1378. X    CtoBStr(tmp->fib->fib_FileName,(ULONG)ptr >> 2L,64L);
  1379. X    dclose(tmp);
  1380. X    packargs[1]=dirlock;
  1381. X    packargs[2]=(ULONG)ptr >> 2L;
  1382. X    packargs[3]=(long)date;
  1383. X    SendPacket(ACTION_SET_DATE,packargs,task);
  1384. X    UnLock(dirlock);
  1385. X    FreeMem(ptr,65L);
  1386. X    }
  1387. Xreturn 0;
  1388. X}
  1389. X
  1390. Xdo_addbuffers()
  1391. X{
  1392. Xlong packargs[7];
  1393. Xlong n;
  1394. Xstruct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
  1395. X
  1396. Xif (!task) { ierror(av[1],510); return 20; }
  1397. Xn=myatoi(av[2],1,32767); if (atoierr) return 20;
  1398. Xpackargs[0]=n;
  1399. XSendPacket(ACTION_MORE_CACHE,packargs,task);
  1400. Xreturn 0;
  1401. X}
  1402. X
  1403. Xdo_relabel()
  1404. X{
  1405. Xlong packargs[7];
  1406. XUBYTE *ptr;
  1407. Xstruct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
  1408. X
  1409. Xif (!task) { ierror(av[1],510); return 20; }
  1410. Xptr=AllocMem(65L,MEMF_PUBLIC);
  1411. XCtoBStr(av[2],(ULONG)ptr >> 2L,64L);
  1412. Xpackargs[0]=(ULONG)ptr >> 2L;
  1413. XSendPacket(ACTION_RENAME_DISK,packargs,task);
  1414. XFreeMem(ptr,65L);
  1415. Xchangedisk(task);
  1416. Xreturn 0;
  1417. X}
  1418. X
  1419. Xdo_diskchange()
  1420. X{
  1421. Xstruct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
  1422. X
  1423. Xif (!task) { ierror(av[1],510); return 20; }
  1424. Xchangedisk(task);
  1425. Xreturn 0;
  1426. X}
  1427. X
  1428. Xchangedisk(task)
  1429. Xstruct MsgPort *task;
  1430. X{
  1431. Xlong packargs[7];
  1432. X
  1433. Xpackargs[0]=1L;
  1434. XSendPacket(ACTION_INHIBIT,packargs,task);
  1435. Xpackargs[0]=0L;
  1436. XSendPacket(ACTION_INHIBIT,packargs,task);
  1437. X}
  1438. END_OF_FILE
  1439. if test 13095 -ne `wc -c <'comm2.c'`; then
  1440.     echo shar: \"'comm2.c'\" unpacked with wrong size!
  1441. fi
  1442. # end of 'comm2.c'
  1443. fi
  1444. if test -f 'sub.c' -a "${1}" != "-c" ; then 
  1445.   echo shar: Will not clobber existing file \"'sub.c'\"
  1446. else
  1447. echo shar: Extracting \"'sub.c'\" \(13255 characters\)
  1448. sed "s/^X//" >'sub.c' <<'END_OF_FILE'
  1449. X
  1450. X/*
  1451. X * SUB.C
  1452. X *
  1453. X * (c)1986 Matthew Dillon     9 October 1986
  1454. X *
  1455. X * Version 2.07M by Steve Drew 10-Sep-87
  1456. X *
  1457. X * Version 4.00A by Carlo Borreo & Cesare Dieni 13-Jan-90
  1458. X *
  1459. X */
  1460. X
  1461. X#define HM_STR 0              /* various HISTORY retrieval modes */
  1462. X#define HM_REL 1
  1463. X#define HM_ABS 2
  1464. X
  1465. Xseterr()
  1466. X{
  1467. Xchar buf[32];
  1468. Xint stat;
  1469. X
  1470. Xsprintf(buf, "%d", Lastresult);
  1471. Xset_var(LEVEL_SET, v_lasterr, buf);
  1472. Xstat = atoi(get_var(LEVEL_SET, v_stat));
  1473. Xif (stat < Lastresult) set_var(LEVEL_SET, v_stat, buf);
  1474. X}
  1475. X
  1476. X#define ISSPACE(c) ((c)==' ' || (c)==9 || (unsigned char)(c)==0xA0)
  1477. X
  1478. Xchar *next_word(str)
  1479. Xregister char *str;
  1480. X{
  1481. Xwhile (*str && ! ISSPACE(*str)) ++str;
  1482. Xwhile (*str &&   ISSPACE(*str)) ++str;
  1483. Xreturn str;
  1484. X}
  1485. X
  1486. Xhasspace(s)
  1487. Xregister char *s;
  1488. X{
  1489. Xfor ( ; *s; s++)
  1490. X    if (ISSPACE(*s)) return 1;
  1491. Xreturn 0;
  1492. X}
  1493. X
  1494. Xchar *compile_av(av, start, end, delim, quote)
  1495. Xchar **av;
  1496. Xunsigned char delim;
  1497. X{
  1498. Xregister char *cstr, *p;
  1499. Xint len;
  1500. Xregister unsigned int i;
  1501. X
  1502. Xlen = 1;
  1503. Xfor (i = start; i < end; ++i) len += strlen(av[i]) + 3;
  1504. Xp = cstr = malloc(len);
  1505. X*cstr = '\0';
  1506. Xfor (i = start; i < end; ++i) {
  1507. X    if (debug) fprintf (stderr, "AV[%2d] :%s:\n", i, av[i]);
  1508. X    if (quote && hasspace(av[i]))
  1509. X        p += sprintf(p, "\"%s\"", av[i]);
  1510. X    else
  1511. X        p += sprintf(p, "%s",     av[i]);
  1512. X    if (i+1 < end) *p++=delim;
  1513. X    }
  1514. X*p='\0';
  1515. Xreturn cstr;
  1516. X}
  1517. X
  1518. X/*
  1519. X * FREE(ptr)   --frees without actually freeing, so the data is still good
  1520. X *               immediately after the free.
  1521. X */
  1522. X
  1523. X
  1524. XFree(ptr)
  1525. Xchar *ptr;
  1526. X{
  1527. Xstatic char *old_ptr;
  1528. X
  1529. Xif (old_ptr) free (old_ptr);
  1530. Xold_ptr = ptr;
  1531. X}
  1532. X
  1533. X/*
  1534. X * Add new string to history (H_head, H_tail, H_len,
  1535. X *  S_histlen
  1536. X */
  1537. X
  1538. Xadd_history(str)
  1539. Xchar *str;
  1540. X{
  1541. X   register struct HIST *hist;
  1542. X
  1543. X   if (H_head != NULL && strcmp(H_head->line, str) == 0)
  1544. X       return(0);
  1545. X   while (H_len > S_histlen)
  1546. X      del_history();
  1547. X   hist = (struct HIST *)malloc (sizeof(struct HIST));
  1548. X   if (H_head == NULL) {
  1549. X      H_head = H_tail = hist;
  1550. X      hist->next = NULL;
  1551. X   } else {
  1552. X      hist->next = H_head;
  1553. X      H_head->prev = hist;
  1554. X      H_head = hist;
  1555. X   }
  1556. X   hist->prev = NULL;
  1557. X   hist->line = malloc (strlen(str) + 1);
  1558. X   strcpy (hist->line, str);
  1559. X   ++H_len;
  1560. X}
  1561. X
  1562. Xdel_history()
  1563. X{
  1564. X   if (H_tail) {
  1565. X      --H_len;
  1566. X      ++H_tail_base;
  1567. X      free (H_tail->line);
  1568. X      if (H_tail->prev) {
  1569. X         H_tail = H_tail->prev;
  1570. X         free (H_tail->next);
  1571. X         H_tail->next = NULL;
  1572. X      } else {
  1573. X         free (H_tail);
  1574. X         H_tail = H_head = NULL;
  1575. X      }
  1576. X   }
  1577. X}
  1578. X
  1579. Xchar *
  1580. Xget_history(ptr)
  1581. Xchar *ptr;
  1582. X{
  1583. X   register struct HIST *hist;
  1584. X   register int len;
  1585. X   int mode = HM_REL;
  1586. X   int num  = 1;
  1587. X   char *str;
  1588. X   char *result = NULL;
  1589. X
  1590. X   if (ptr[1] >= '0' && ptr[1] <= '9') {
  1591. X      mode = HM_ABS;
  1592. X      num  = atoi(&ptr[1]);
  1593. X      goto skip;
  1594. X   }
  1595. X   switch (ptr[1]) {
  1596. X   case '!':
  1597. X      break;
  1598. X   case '-':
  1599. X      num += atoi(&ptr[2]);
  1600. X      break;
  1601. X   default:
  1602. X      mode = HM_STR;
  1603. X      str  = ptr + 1;
  1604. X      break;
  1605. X   }
  1606. Xskip:
  1607. X   switch (mode) {
  1608. X   case HM_STR:
  1609. X      len = strlen(str);
  1610. X      for (hist = H_head; hist; hist = hist->next) {
  1611. X         if (strncmp(hist->line, str, len) == 0 && *hist->line != '!') {
  1612. X            result = hist->line;
  1613. X            break;
  1614. X         }
  1615. X      }
  1616. X      break;
  1617. X   case HM_REL:
  1618. X      for (hist = H_head; hist && num--; hist = hist->next);
  1619. X      if (hist)
  1620. X         result = hist->line;
  1621. X      break;
  1622. X   case HM_ABS:
  1623. X      len = H_tail_base;
  1624. X      for (hist = H_tail; hist && len != num; hist = hist->prev, ++len);
  1625. X      if (hist)
  1626. X         result = hist->line;
  1627. X      break;
  1628. X   }
  1629. X   if (result) {
  1630. X      fprintf(stderr,"%s\n",result);
  1631. X      return(result);
  1632. X   }
  1633. X   printf("History failed\n");
  1634. X   return ("");
  1635. X}
  1636. X
  1637. Xreplace_head(str)
  1638. Xchar *str;
  1639. X{
  1640. X   if (str == NULL)
  1641. X      str = "";
  1642. X   if (H_head) {
  1643. X      free (H_head->line);
  1644. X      H_head->line = malloc (strlen(str)+1);
  1645. X      strcpy (H_head->line, str);
  1646. X   }
  1647. X}
  1648. X
  1649. X
  1650. XpError(str)
  1651. Xchar *str;
  1652. X{
  1653. Xint ierr = (long)IoErr();
  1654. Xierror(str, ierr);
  1655. X}
  1656. X
  1657. Xierror(str, err)
  1658. Xregister char *str;
  1659. X{
  1660. X   register struct PERROR *per = Perror;
  1661. X
  1662. X   if (err) {
  1663. X      for (; per->errstr; ++per) {
  1664. X         if (per->errnum == err) {
  1665. X            fprintf (stderr, "%s%s%s\n",
  1666. X                  per->errstr,
  1667. X                  (str) ? ": " : "",
  1668. X                  (str) ? str : "");
  1669. X            return ((short)err);
  1670. X         }
  1671. X      }
  1672. X      fprintf (stderr, "Unknown DOS error %d %s\n", err, (str) ? str : "");
  1673. X   }
  1674. X   return ((short)err);
  1675. X}
  1676. X
  1677. X/*
  1678. X * Disk directory routines
  1679. X *
  1680. X * dptr = dopen(name, stat)
  1681. X *    struct DPTR *dptr;
  1682. X *    char *name;
  1683. X *    int *stat;
  1684. X *
  1685. X * dnext(dptr, name, stat)
  1686. X *    struct DPTR *dptr;
  1687. X *    char **name;
  1688. X *    int  *stat;
  1689. X *
  1690. X * dclose(dptr)                  -may be called with NULL without harm
  1691. X *
  1692. X * dopen() returns a struct DPTR, or NULL if the given file does not
  1693. X * exist.  stat will be set to 1 if the file is a directory.  If the
  1694. X * name is "", then the current directory is openned.
  1695. X *
  1696. X * dnext() returns 1 until there are no more entries.  The **name and
  1697. X * *stat are set.  *stat = 1 if the file is a directory.
  1698. X *
  1699. X * dclose() closes a directory channel.
  1700. X *
  1701. X */
  1702. X
  1703. Xstruct DPTR *
  1704. Xdopen(name, stat)
  1705. Xchar *name;
  1706. Xint *stat;
  1707. X{
  1708. Xstruct DPTR *dp;
  1709. X
  1710. X*stat = 0;
  1711. Xdp = (struct DPTR *)malloc(sizeof(struct DPTR));
  1712. Xif (*name == '\0')
  1713. X    dp->lock = DupLock(Myprocess->pr_CurrentDir);
  1714. Xelse
  1715. X    dp->lock = Lock (name,ACCESS_READ);
  1716. Xif (dp->lock == NULL) {
  1717. X    free (dp);
  1718. X    return NULL;
  1719. X    }
  1720. Xdp->fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  1721. Xif (!Examine (dp->lock, dp->fib)) {
  1722. X    pError (name);
  1723. X    dclose (dp);
  1724. X    return NULL;
  1725. X    }
  1726. Xif (dp->fib->fib_DirEntryType >= 0) *stat = 1;
  1727. Xreturn dp;
  1728. X}
  1729. X
  1730. Xdnext(dp, pname, stat)
  1731. Xstruct DPTR *dp;
  1732. Xchar **pname;
  1733. Xint *stat;
  1734. X{
  1735. Xif (dp == NULL) return (0);
  1736. X   if (ExNext (dp->lock, dp->fib)) {
  1737. X      *stat = (dp->fib->fib_DirEntryType < 0) ? 0 : 1;
  1738. X      *pname = dp->fib->fib_FileName;
  1739. X      return (1);
  1740. X   }
  1741. X   return (0);
  1742. X}
  1743. X
  1744. X
  1745. Xdclose(dp)
  1746. Xstruct DPTR *dp;
  1747. X{
  1748. X   if (dp == NULL)
  1749. X      return (1);
  1750. X   if (dp->fib)
  1751. X      FreeMem (dp->fib,(long)sizeof(*dp->fib));
  1752. X   if (dp->lock)
  1753. X      UnLock (dp->lock);
  1754. X   free (dp);
  1755. X   return (1);
  1756. X}
  1757. X
  1758. X
  1759. Xisdir(file)
  1760. Xchar *file;
  1761. X{
  1762. X   register struct DPTR *dp;
  1763. X   int stat;
  1764. X
  1765. X   stat = 0;
  1766. X   if (dp = dopen (file, &stat))
  1767. X      dclose(dp);
  1768. X   return (stat == 1);
  1769. X}
  1770. X
  1771. X
  1772. Xfree_expand(av)
  1773. Xregister char **av;
  1774. X{
  1775. X   char **base = av;
  1776. X
  1777. X   if (av) {
  1778. X      while (*av) {
  1779. X         free (*av);
  1780. X         ++av;
  1781. X      }
  1782. X      free (base);
  1783. X   }
  1784. X}
  1785. X
  1786. X/*
  1787. X * EXPAND(base,pac)
  1788. X *    base           - char * (example: "df0:*.c")
  1789. X *    pac            - int  *  will be set to # of arguments.
  1790. X *
  1791. X * 22-May-87 SJD.  Heavily modified to allow recursive wild carding and
  1792. X *                 simple directory/file lookups. Returns a pointer to
  1793. X *                 an array of pointers that contains the full file spec
  1794. X *                 eg. 'df0:c/sear*' would result in : 'df0:C/Search'
  1795. X *
  1796. X *                 Now no longer necessary to Examine the files a second time
  1797. X *                 in do_dir since expand will return the full file info
  1798. X *                 appended to the file name. Set by formatfile().
  1799. X *                 eg. fullfilename'\0'rwed  NNNNNN NNNN  DD-MMM-YY HH:MM:SS
  1800. X *
  1801. X *                 Caller must call free_expand when done with the array.
  1802. X *
  1803. X * base             bname =       ename =
  1804. X * ------           -------       -------
  1805. X *  "*"               ""            "*"
  1806. X *  "!*.info"         ""            "*.info" (wild_exclude set)
  1807. X *  "su*d/*"          ""            "*"      (tail set)
  1808. X *  "file.*"          ""            "file.*"
  1809. X *  "df0:c/*"         "df0:c"       "*"
  1810. X *  ""                ""            "*"
  1811. X *  "df0:.../*"       "df0:"        "*"      (recur set)
  1812. X *  "df0:sub/.../*"   "df0:sub"     "*"      (recur set)
  1813. X *
  1814. X * ---the above base would be provided by execom.c or do_dir().
  1815. X * ---the below base would only be called from do_dir().
  1816. X *
  1817. X *  "file.c"          "file.c"      ""       if (dp == 0) fail else get file.c
  1818. X *  "df0:"            "df0:"        "*"
  1819. X *  "file/file"       "file/file"   ""       (dp == 0) so fail
  1820. X *  "df0:.../"        "df0:"        "*"      (recur set)
  1821. X *
  1822. X */
  1823. X
  1824. X
  1825. Xchar **
  1826. Xexpand(base, pac)
  1827. Xchar *base;
  1828. Xint *pac;
  1829. X{
  1830. X   register char *ptr;
  1831. X   char **eav = (char **)malloc(sizeof(char *) * (2));
  1832. X   short eleft, eac;
  1833. X   char *name;
  1834. X   char *svfile();
  1835. X   char *bname, *ename, *tail;
  1836. X   int stat, recur, scr, bl;
  1837. X   register struct DPTR *dp;
  1838. X
  1839. X   *pac = recur = eleft = eac = 0;
  1840. X
  1841. X   base = strcpy(malloc(strlen(base)+1), base);
  1842. X   for (ptr = base; *ptr && *ptr != '?' && *ptr != '*'; ++ptr);
  1843. X
  1844. X   if (!*ptr)   /* no wild cards */
  1845. X      --ptr;
  1846. X   else
  1847. X      for (; ptr >= base && !(*ptr == '/' || *ptr == ':'); --ptr);
  1848. X
  1849. X   if (ptr < base) {
  1850. X      bname = strcpy (malloc(1), "");
  1851. X   } else {
  1852. X      scr = ptr[1];
  1853. X      ptr[1] = '\0';
  1854. X      if (!strcmp(ptr-3,".../")) {
  1855. X         recur = 1;
  1856. X         *(ptr-3) = '\0';
  1857. X      }
  1858. X      bname = strcpy (malloc(strlen(base)+2), base);
  1859. X      ptr[1] = scr;
  1860. X   }
  1861. X   bl = strlen(bname);
  1862. X   ename = ++ptr;
  1863. X   for (; *ptr && *ptr != '/'; ++ptr);
  1864. X   scr = *ptr;
  1865. X   *ptr = '\0';
  1866. X   if (scr) ++ptr;
  1867. X   tail = ptr;
  1868. X
  1869. X   if ((dp = dopen (bname, &stat)) == NULL || (stat == 0 && *ename)) {
  1870. X      free (bname);
  1871. X      free (base);
  1872. X      free (eav);
  1873. X      return (NULL);
  1874. X   }
  1875. X
  1876. X   if (!stat) {                /* eg. 'dir file' */
  1877. X      char *p,*s;
  1878. X      for(s = p = bname; *p; ++p) if (*p == '/' || *p == ':') s = p;
  1879. X      if (s != bname) ++s;
  1880. X      *s ='\0';
  1881. X      eav[eac++] = svfile(bname,dp->fib->fib_FileName,dp->fib);
  1882. X      goto done;
  1883. X   }
  1884. X   if (!*ename) ename = "*";    /* eg. dir df0: */
  1885. X   if (*bname && bname[bl-1] != ':' && bname[bl-1] != '/') { /* dir df0:c */
  1886. X      bname[bl] = '/';
  1887. X      bname[++bl] = '\0';
  1888. X   }
  1889. X   while ((dnext (dp, &name, &stat)) && !breakcheck()) {
  1890. X        int match = compare_ok(ename,name,0);
  1891. X      if (match && !(!recur && *tail)) {
  1892. X         if (eleft < 2) {
  1893. X               char **scrav = (char **)malloc(sizeof(char *) * (eac + 10));
  1894. X               movmem (eav, scrav, (eac + 1) << 2);
  1895. X               free (eav);
  1896. X               eav = scrav;
  1897. X               eleft = 10;
  1898. X         }
  1899. X         eav[eac++] = svfile(bname,name,dp->fib);
  1900. X         --eleft;
  1901. X      }
  1902. X      if ((*tail && match) || recur) {
  1903. X         int alt_ac;
  1904. X         char *search, **alt_av, **scrav;
  1905. X         BPTR lock;
  1906. X
  1907. X         if (!stat)           /* expect more dirs, but this not a dir */
  1908. X            continue;
  1909. X         lock = CurrentDir (dp->lock);
  1910. X         search = malloc(strlen(ename)+strlen(name)+strlen(tail)+5);
  1911. X         strcpy (search, name);
  1912. X         strcat (search, "/");
  1913. X         if (recur) {
  1914. X            strcat(search, ".../");
  1915. X            strcat(search, ename);
  1916. X         }
  1917. X         strcat (search, tail);
  1918. X         scrav = alt_av = expand (search, &alt_ac);
  1919. X         /* free(search); */
  1920. X         CurrentDir (lock);
  1921. X         if (scrav) {
  1922. X            while (*scrav) {
  1923. X               int l;
  1924. X               if (eleft < 2) {
  1925. X                  char **scrav = (char **)malloc(sizeof(char *) * (eac + 10));
  1926. X                  movmem (eav, scrav, (eac + 1) << 2);
  1927. X                  free (eav);
  1928. X                  eav = scrav;
  1929. X                  eleft = 10;
  1930. X               }
  1931. X
  1932. X               l = strlen(*scrav);
  1933. X               scrav[0][l] = ' ';
  1934. X               eav[eac] = malloc(bl+l+45);
  1935. X               strcpy(eav[eac], bname);
  1936. X               strcat(eav[eac], *scrav);
  1937. X               eav[eac][l+bl] = '\0';
  1938. X
  1939. X               free (*scrav);
  1940. X               ++scrav;
  1941. X               --eleft, ++eac;
  1942. X            }
  1943. X            free (alt_av);
  1944. X         }
  1945. X      }
  1946. X   }
  1947. Xdone:
  1948. X   dclose (dp);
  1949. X   *pac = eac;
  1950. X   eav[eac] = NULL;
  1951. X   free (bname);
  1952. X   free (base);
  1953. X   if (eac) {
  1954. X      return (eav);
  1955. X   }
  1956. X   free (eav);
  1957. X   return (NULL);
  1958. X}
  1959. X
  1960. Xstrupr(s)
  1961. Xregister char *s;
  1962. X{
  1963. Xwhile (*s) *s=toupper(*s), s++;
  1964. X}
  1965. X
  1966. X/*
  1967. X * Compare a wild card name with a normal name
  1968. X */
  1969. X
  1970. Xcompare_ok(wild, name, casedep)
  1971. Xchar *wild, *name;
  1972. X{
  1973. Xint queryflag;
  1974. Xchar buf[260], wildbuf[260], *lowname;
  1975. X
  1976. Xif (queryflag=(*wild=='&')) wild++;
  1977. Xif (*wild=='!') *wild='~';
  1978. X
  1979. Xif (! casedep) {
  1980. X    strupr(wild);
  1981. X    strcpy(buf,name);
  1982. X    strupr(buf);
  1983. X    lowname=buf;
  1984. X    }
  1985. Xelse lowname=name;
  1986. X
  1987. XPreParse(wild, wildbuf);
  1988. Xif ( ! PatternMatch(wildbuf,lowname)) return 0;
  1989. X
  1990. Xif (queryflag) {
  1991. X    printf("Select \23337m%-16s\2330m [y/n] ? ",name);
  1992. X    gets(buf);
  1993. X    return (toupper(*buf)=='Y');
  1994. X    }
  1995. Xreturn 1;
  1996. X}
  1997. X
  1998. Xchar *svfile(s1,s2,fib)
  1999. Xchar *s1,*s2;
  2000. XFIB *fib;
  2001. X{
  2002. Xchar *p = malloc (strlen(s1)+strlen(s2)+45);
  2003. Xstrcpy(p, s1);
  2004. Xstrcat(p, s2);
  2005. Xformatfile(p,fib);
  2006. Xreturn p;
  2007. X}
  2008. X
  2009. X/* will have either of these formats:
  2010. X *
  2011. X *    fullfilename'\0'hsparwed   <Dir>       DD-MMM-YY HH:MM:SS\n'\0'
  2012. X *    fullfilename'\0'hsparwed  NNNNNN NNNN  DD-MMM-YY HH:MM:SS\n'\0'
  2013. X *                              1111111111222222222233333333334 4  4
  2014. X *                    01234567890123456789012345678901234567890 1  2
  2015. X */
  2016. Xformatfile(str,fib)
  2017. Xchar *str;
  2018. XFIB *fib;
  2019. X{
  2020. Xchar *dates();
  2021. Xint i;
  2022. Xwhile(*str++);
  2023. Xfor (i=7; i>=0; i--)
  2024. X    *str++ = ((fib->fib_Protection & (1L<<i)) ? "hspa----" : "----rwed")[7-i];
  2025. Xif (fib->fib_DirEntryType < 0)
  2026. X  sprintf(str,"  %6ld %4ld  ", (long)fib->fib_Size, (long)fib->fib_NumBlocks);
  2027. Xelse strcpy(str,"   <Dir>       ");
  2028. Xstrcat(str,dates(&fib->fib_Date));
  2029. X}
  2030. X
  2031. X/* Sort routines */
  2032. X
  2033. Xlong cmp(s1, s2)
  2034. Xchar **s1, **s2;
  2035. X{
  2036. Xreturn (long)Strcmp(*s1, *s2);
  2037. X}
  2038. X
  2039. XCmp() {
  2040. X#asm
  2041. X    public    _geta4
  2042. X    movem.l    d2-d3/a4/a6,-(sp)
  2043. X    movem.l    a0/a1,-(sp)
  2044. X    bsr    _geta4
  2045. X    bsr    _cmp
  2046. X    addq.l    #8,sp
  2047. X    movem.l    (sp)+,d2-d3/a4/a6
  2048. X#endasm
  2049. X}
  2050. X
  2051. XQuickSort(av, n)
  2052. Xchar *av[];
  2053. Xint n;
  2054. X{
  2055. XQSort(av, (long)n, 4L, Cmp);
  2056. X}
  2057. END_OF_FILE
  2058. if test 13255 -ne `wc -c <'sub.c'`; then
  2059.     echo shar: \"'sub.c'\" unpacked with wrong size!
  2060. fi
  2061. # end of 'sub.c'
  2062. fi
  2063. echo shar: End of archive 2 \(of 4\).
  2064. cp /dev/null ark2isdone
  2065. MISSING=""
  2066. for I in 1 2 3 4 ; do
  2067.     if test ! -f ark${I}isdone ; then
  2068.     MISSING="${MISSING} ${I}"
  2069.     fi
  2070. done
  2071. if test "${MISSING}" = "" ; then
  2072.     echo You have unpacked all 4 archives.
  2073.     rm -f ark[1-9]isdone
  2074. else
  2075.     echo You still need to unpack the following archives:
  2076.     echo "        " ${MISSING}
  2077. fi
  2078. ##  End of shell archive.
  2079. exit 0
  2080. -- 
  2081. Submissions to comp.sources.amiga and comp.binaries.amiga should be sent to:
  2082.     amiga@cs.odu.edu    
  2083. or    amiga@xanth.cs.odu.edu    ( obsolescent mailers may need this address )
  2084. or    ...!uunet!xanth!amiga    ( very obsolescent mailers need this address )
  2085.  
  2086. Comments, questions, and suggestions s should be addressed to ``amiga-request''
  2087. (only use ``amiga'' for submissions) at the above addresses.
  2088.